const $ = require('./tool.js');
const common = require('./common.js');

function Xhr(args) {
  args = args || {};
  this.headers = {}
  this.method = 'GET'
  this.url = ''
  this.type = 'json'
  this.responseText = ''
  this.status = ''
  this.readyState = ''
  this.open = function(method, url) {
    this.method = method;
    this.url = url;
  }
  this.requestTask = '';
  this.abort = function() {
    this.requestTask.abort();
  }
  this.send = function(body) {
    var self = this;
    this.requestTask = wx.request({
      url: this.url,
      method: this.method,
      data: body,
      header: this.headers,
      complete: function(ret) {
        self.readyState = 4;
        if (ret.data) {
          self.status = ret.statusCode;
          self.responseText = ret.data;
        } else {
          self.responseText = ret;
        }
        if (typeof self.onreadystatechange == 'function') self.onreadystatechange();
      }
    })
  }
  this.setRequestHeader = function(k, v) {
    this.headers[k] = v;
  }
  for (var k in args) this[k] = args[k];
}
$.Storage.setLocalStorage({
  setItem: wx.setStorageSync,
  getItem: wx.getStorageSync,
  removeItem: wx.removeStorageSync,
  clear: wx.clearStorageSync
})
wx.$ = {
  ...$,
  Xhr,
  styleSheet: function(styles, o) {
    return $.string(styles)._eval(o || {});
  },
  computPX: function(n) {
    return n * wx.getSystemInfoSync().windowWidth / 750;
  },
  platform: 'WeChatMiniApp',
  alertx: function(msg, next, args) {
    args = args || {};
    wx.showModal($.merge({
      title: '提示',
      content: msg && typeof msg == 'object' ? JSON.stringify(msg) : msg,
      showCancel: false,
      success: next
    }, args))
  },
  alert: function(msg,args) {
    return new Promise(next => {
      this.alertx(msg,next,args)
    })
  },
  confirmx: function(msg, next, args) {
    args = args || {};
    wx.showModal($.merge({
      title: '提示',
      content: msg && typeof msg == 'object' ? JSON.stringify(msg) : msg,
      showCancel: true,
      success: function(ret) {
        if (ret.confirm) {
          next(ret);
        } else {
          if (typeof args.cancel === 'function') args.cancel(ret);
        }
      }
    }, args))
  },
  confirm: function(msg,args) {
    return new Promise((resolve, reject) => {
      this.confirmx(msg,resolve, args)
    })
  },
  toask:function(msg){
    wx.showToast({
      title: msg,
      icon: 'none',
      duration: 3000
    })
    return new Promise(next => {
      setTimeout(next,3000)
    })
  },
  location: function() {
    var pages = getCurrentPages();
    pages.pathname = '/' + pages[pages.length - 1].route.split('?')[0];
    return pages.pathname;
  },
  $go: function(url, openType) {
    url = url.replace(/^\/live/,'plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin');
    var pageName = url.split('?')[0];
    if(!$.Storage.get('navigates')) $.Storage.set('navigates',{});
    openType = openType || $.Storage.get('navigates')[pageName] || 'navigateTo';
    openType = openType == 'navigateTo' && getCurrentPages().length >= 10 ? 'redirectTo' : openType;
    var miniAppReg = /^(.+)appId=([A-Z,a-z,0-9]+)$/;
    if(miniAppReg.test(url)){
      var appId = ''; 
      url = url.replace(miniAppReg,function($0,$1,$2){
        appId = $2;
        return $1.replace(/&$/,'');
      })
      wx.navigateToMiniProgram({
        appId,
        path:url.indexOf('miniApp') == 0 ? '' : url
      })
    }else if (typeof this[openType] == 'function') {
      this[openType](typeof url == 'object' ? url : { url })
    }
  },
  reEnter: function(url) {
    $.Storage.clear(0);
    this.$go(url, 'reLaunch');
  },
  ...wx,
  App: function(args) {
    var _this = this;
    args = common.call(this, args, 'app');
    function launch(){
      var options = wx.getEnterOptionsSync();
      if (args.init) args.init(options);
      //登录
      $.Storage.set('logined', false, 2);
      var afters = new $.Item();
      afters._push(function(_next) {
        if (args.onLaunch) args.onLaunch(options);
        _next();
      })
      var autoLogin = function(next) {
        if ($.Storage.get('logined', 2)) {
          afters = new $.Item();
          afters._push(function(_next){_next()});
          $.Storage.set('logined', false);
        }
        afters._push(function(_next) {
          next();
          _next();
        })
        if(afters.length == 2){
          args.autoLogin(function() {
            afters._do();
            $.Storage.set('logined', true);
          }, function(error,type) {
            afters = new $.Item();
            if (!$.Storage.get('logined')) {
              afters._push(function(_next) {
                if (args.onLaunch) args.onLaunch(options);
                _next();
              })
            }
            _this.reEnter(args.onLogin ? args.onLogin : '/pages/err/err?msg=' + error + (type ? '\r\n错误类型:' + type : ''));
          },options)
        }
      }
      $.Storage.set('autoLogin', autoLogin, 2);
      //ajax拦截
      if (args.Interceptor) $.Storage.set('loginAction', args.Interceptor, {
        type: 2
      });
    }
    if(!wx.vue){
      launch();
    }else{
      if(!$.Storage.get('autoLogin')){
        App(args);
      }
    }
  },
  vue: function(args) {
    args = common.call(this, args, 'vue');
    function login(_this,meth){
      if (args.noLogin || $.Storage.get('logined')) {
        if (args[meth]) args[meth].call(_this, _this.options);
      } else {
        $.Storage.get('autoLogin')(function() {
          if (args[meth]) args[meth].call(_this, _this.options);
        })
      }
    }
    args.data = args.data || {}
    ///构建依据
    if(args.data.LIST_count){
      ///存放数据
      args.data.LIST_datas = []
      args.data.LIST_index = 0
      let lists = []
      for(let i = 0; i < args.data.LIST_count; i ++){
        let list = this.list()
        lists.push(list)
        args.data.LIST_datas.push(list.getData())
      }
      ///初始化
      args.methods.LIST_init = function(_lists){
        let LIST_datas = []
        lists = []
        for(let i = 0; i < _lists.length; i ++){
          let list = _lists[i]
          lists.push(list)
          LIST_datas.push(list.getData())
        }
        this.setData({LIST_datas})
      }
      ///获取
      args.methods.LIST_get = function(index){
        return lists
      }
      ///设置
      args.methods.LIST_set = function(_lists){
        lists = _lists
      }
      if(!args.methods.onPullDownRefresh){
        args.methods.onPullDownRefresh = function () {
          this.LIST_refresh(this.getData('LIST_index'),()=>{
            wx.stopPullDownRefresh()
          })
        }
      }
      if(!args.methods.onReachBottom){
        args.methods.onReachBottom = function () {
          this.LIST_load(this.getData('LIST_index'))
        }
      }
      ///初始全部加载
      args.methods.LIST_loads = function(){
        for(let i = 0; i < lists.length; i ++) this.LIST_load(i)
      }
      ///指定加载
      args.methods.LIST_load = function (index,next) {
        index = index || 0
        if(typeof index == 'object') index = this.getData('LIST_index')
        let list = lists[index];
        let LIST_datas = this.getData('LIST_datas')
        list.load(() => {
          LIST_datas[index] = list.getData()
          this.setData({
            LIST_datas
          })
          if (typeof next == 'function') next.call(this)
        })
      }
      ///指定重置
      args.methods.LIST_refresh = function (index,next) {
        index = index || 0
        if(typeof index == 'object') index = this.getData('LIST_index')
        let list = lists[index];
        let LIST_datas = this.getData('LIST_datas')
        list.refresh(() => {
          LIST_datas[index] = list.getData()
          this.setData({
            LIST_datas
          });
          if (typeof next == 'function') next.call(this);
        });
      }
    }
    Page({
      data: args.data,
      ...args.methods,
      getData: function(key) {
        return this.data[key];
      },
      onLoad: function(options) {
        this.options = options;
        if(args.created) login(this,'created');
      },
      onReady: function() {
        if(args.mounted || (!args.created && !args.mounted)) login(this,'mounted');
      },
      onShareAppMessage: function(ret) {
        var rc = args.methods.onShareAppMessage ? args.methods.onShareAppMessage.call(this, ret) : {};
        if (typeof $.Storage.get('shareAppMessage') == 'function') $.Storage.get('shareAppMessage').call(this,ret,rc)
        return rc;
      }
    });
  },
  component: function(args) {
    args = common.call(this, args, 'component');
    if (args.props) for (var k in args.props) args.props[k].value = args.props[k].default;
    Component({
      options: {
        multipleSlots: true
      },
      properties: args.props,
      //data: args.data(),
      methods: {
        ...args.methods,
        getData: function(key) {
          return this.data[key];
        }
      },
      attached: function() {
        if (typeof args.data == 'function') this.setData(args.data.call(this));
        args.created && args.created.call(this);
      },
      ready: function() {
        args.mounted && args.mounted.call(this);
      }
    })
  },
  ajax: function(url, callback, args) {
    args = args || {};
    var _this = this;
    if(args.loading === false) args.loading = {}
    args.loading = args.loading || {
      open: function() {
        wx.showLoading();
        if (_this.setData) _this.setData({
          submiting: true
        });
      },
      close: function() {
        if (_this.setData) {
          setTimeout(function() {
            wx.hideLoading();
            _this.setData({
              submiting: false
            });
          }, 3000)
        } else {
          wx.hideLoading();
        }
      }
    };
    if($.Storage.get('tcbEnvId') && !args.UNTCB && wx.$.cloud) {
      wx.$.cloud.ajax(url, callback, args);
      return false;
    }
    args.xhr = new Xhr();
    url = url.replace(new RegExp('^{(.+)}', 'g'), function($0, $1) {
      return $.Storage.get($1) || ('{' + $1 + '}');
    })
    if (url.indexOf('http') != 0) url = $.Storage.get('APIURL') + url;
    var ajax = new $.Ajax(url, function(ret) {
      if (args.errNotify !== false && ret.errorMsg) {
        wx.showToast({
          title: '成功',
          icon: 'none',
          duration: 5000,
          title: ret.errorMsg
        })
      }
      callback(ret);
    }, args);
    ajax.action();
  },
  list: function(args) {
    args = args || {};
    if($.Storage.get('tcbEnvId') && !args.UNTCB && wx.$.cloud) {
      return wx.$.cloud.list(args);
    }
    var url = '', getArgs = args.get || '';
    if (typeof getArgs == 'string') {
      url = getArgs;
      getArgs = {};
    } else {
      url = getArgs.url;
      getArgs.url = undefined;
    }
    if(typeof url == 'string'){
      getArgs.xhr = new Xhr();
      url = url.replace(new RegExp('^{(.+)}', 'g'), function($0, $1) {
        return $.Storage.get($1) || ('{' + $1 + '}');
      })
      if (url.indexOf('http') != 0) url = $.Storage.get('APIURL') + url;
      args.get = new $.Ajax(url, '', getArgs);
    }
    return new $.List(args);
  },
  Upload: function(args) {
    args = args || {};
    var _this = this;
    this.id = args.id;
    this.url = args.url;
    if (this.url.indexOf('http') != 0) this.url = $.Storage.get('APIURL') + this.url;
    this.callback = args.callback || new Function();
    this.limit = args.limit ? args.limit : 1;
    this.maxSize = args.maxSize != undefined ? args.maxSize : (10 * 1024 * 1024);
    this.header = args.header ? args.header : [];
    this.fileKey = args.fileKey || 'file';
    this.accept = args.accept || '*';
    this.urlFormat = args.urlFormat;
    this.uploadFile = args.uploadFile;
    this.upIndex = args.upIndex;
    this.init = function(args) {
      args = args || {};
      $.merge(this, args);
      this.uploaded.splice(0, this.uploaded.length);
    }
    this.click = function() {
      if(/image/.test(this.accept)){
        wx.chooseMedia({
          count: this.upIndex >= 0 ? 1 : (this.limit - this.uploaded.length),
          sourceType: args.sourceType,
          camera:args.camera,
          sizeType:args.sizeType,
          success:function(res) {
            _this.uploads(res.tempFiles);
          }
        })
      }else{
        wx.chooseMessageFile({
          count: this.upIndex >= 0 ? 1 : (this.limit - this.uploaded.length),
          success:function(res) {
            _this.uploads(res.tempFiles);
          }
        })
      }
    }
    this.uploaded = [];
    this.remove = function(i) {
      this.uploaded.splice(i, 1);
      this.callback(this.uploaded);
    }
    this.uploads = function(files,isCompress) {
      var fileItems = new $.Item(),
        errs = [];
      for (var i = 0; i < files.length; i++) {
        (function(i) {
          fileItems._push(function(next) {
            function _next(ret) {
              if (!ret.errorMsg) {
                ret = _this.urlFormat ? _this.urlFormat.call(_this,ret) : ret;
                if(ret.url && /undefined/.test(ret.url)){
                  errs.push('上传出错,请重试')
                }else{
                  if(_this.upIndex >= 0){
                    _this.uploaded[-(-_this.upIndex)] = ret;
                    _this.upIndex = undefined;
                  }else{
                    _this.uploaded.push(ret);
                  }
                }
              } else {
                errs.push(ret.errorMsg)
              }
              next();
            }
            _this.upload(files[i], _next);
          })
        })(i)
      }
      fileItems._push(function() {
        _this.callback(_this.uploaded, errs.join(','));
      });
      fileItems._do();
    }
    this.beforeAction = args.beforeAction;
    this.upload = function(fileObject, next) {
      if (this.uploaded.length >= this.limit) {
        next({
          errorMsg: '已超过上传数量限制'
        });
        return false;
      }
      var ajaxConfig = $.clone(args.ajax || {});
      fileObject.name = (fileObject.tempFilePath || fileObject.path).replace('http://tmp/','');
      if (typeof this.beforeAction == 'function') {
        this.beforeAction.call(this, function (formDatas) {
          uploadFile();
        }, fileObject, ajaxConfig)
      } else {
        uploadFile();
      }
      function uploadFile(){
        if(_this.uploadFile){
          _this.uploadFile.call(_this,fileObject, ajaxConfig,next);
        }else{
          var formData = {},src = fileObject.tempFilePath || fileObject.path;
          var ajaxHeader = (ajaxConfig.header || []).concat($.Storage.get('ajaxHeader') || []),header = {};
          for (var i = 0; i < ajaxHeader.length; i++) header[ajaxHeader[i].key] = ajaxHeader[i].value;
          formData.filename = fileObject.name;
          if(ajaxConfig.formData) for(var key in ajaxConfig.formData) formData[key] = ajaxConfig.formData[key];
          wx.showLoading();
          if(!_this.quality) {
            if(fileObject.size){
              _this.quality = _this.maxSize / fileObject.size * 100 //根据最大大小压缩
              if(_this.quality > 100) _this.quality = 100
            }else{
              _this.quality = 100
            }
          }
          if(/\.(png)|(jpg)|(jpeg)$/.test(src)){
            wx.compressImage({
              src, // 图片路径
              quality: _this.quality, // 压缩质量
              compressedWidth:_this.compressedWidth,
              compressedHeight:_this.compressedHeight,
              success(res){
                  wx.uploadFile({
                    url: ajaxConfig.url || _this.url,
                    name: _this.fileKey,
                    methed: ajaxConfig.meth || 'POST',
                    filePath: res.tempFilePath,
                    header: header,
                    formData:formData,
                    complete(ret) {
                      wx.hideLoading()
                      next($.string(ret.data).parse())
                    }
                  })
              },
              fail(){
                wx.hideLoading()
                next({errorMsg:'图片压缩失败'})
              }
            })
          }else{
            wx.uploadFile({
              url: ajaxConfig.url || _this.url,
              name: _this.fileKey,
              methed: ajaxConfig.meth || 'POST',
              filePath: src,
              header: header,
              formData:formData,
              complete(ret) {
                wx.hideLoading()
                next($.string(ret.data).parse())
              }
            })
          }
        }
      }
    }
  },
  showFile:function(url,isImg,type){
    if (isImg || /png|jpg|jpeg|gif|svg/i.test(url)){
      wx.previewImage({
        urls: [url]
      })
    }else{
      wx.showModal({
        title: '文件预览提示',
        content: '是否下载文件进行查看?',
        showCancel: true,
        success: function(ret) {
          if (ret.confirm) {
            wx.downloadFile({
              url: url,
              success: function (res) {
                wx.openDocument({
                  filePath: res.tempFilePath || res.path,
                  fileType:type,
                  fail:function(e){
                    wx.showModal({
                      title:'提示',
                      content: '打开文件失败!' + e.errMsg,
                      showCancel:false
                    })
                  }
                })
              },
              fail:function(e){
                wx.showModal({
                  title:'提示',
                  content:'下载文件失败!' + e.errMsg,
                  showCancel:false
                })
              }
            })
          }
        }
      })
    }
  }
}
common.call(wx.$);